package org.ajmm.obsearch.index.utils;

import java.util.Date;

import cern.jet.random.engine.MersenneTwister;
import cern.jet.random.engine.RandomSeedGenerator;

/*
 OBSearch: a distributed similarity search engine
 This project is to similarity search what 'bit-torrent' is to downloads.
 Copyright (C)  2007 Arnoldo Jose Muller Molina

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * A class used to generate random numbers. We use an implementation that seems
 * to be better than the one provided by JDK. Every time you instantiate this
 * class, a new seed will be generated!
 */
public class OBRandom {

    /**
     * A nice random seed generator
     */
    private static final transient RandomSeedGenerator seedGenerator = new RandomSeedGenerator();

    /**
     * Why to use Knuth's random generator when we can get a super-duper Mersene
     * Twister random number generator!
     */
    private MersenneTwister r;

    /**
     * When you create an OBRandom, a seed is generated by using a special seed
     * generator.
     */
    public OBRandom() {
        // r = new MersenneTwister(seedGenerator.nextSeed());
        r = new MersenneTwister(new Date());
    }

    /**
     * Returns a 32 bit uniformly distributed random number in the open unit
     * interval (0.0f,1.0f) (excluding 0.0f and 1.0f)
     */
    public float nextFloat() {
        float res = r.nextFloat();
        assert 0.0f < res &&  res < 1.0f;
        return res;
    }

    /**
     * Returns the next  boolean value from this random number generator's sequence.
     */
    public boolean nextBoolean() {
        return r.nextInt() >= 0;
    }

    /**
     * Returns a pseudorandom, uniformly distributed int value between 0
     * (inclusive) and the specified value (exclusive)
     * @param n
     *                the bound on the random number to be returned. Must be
     *                positive.
     * @return the next pseudorandom, uniformly distributed int value between 0
     *         (inclusive) and n (exclusive) from this random number generator's
     *         sequence
     */
    public int nextInt(int n) {
        int res = (int) (nextFloat() * (n));
        // res--;
        assert res >= 0 && res < n : "Result of res:" + res;
        return res;
    }

}
